﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Dapper;
using DapperExtensions;
using MaximServices.Data;
using MaximServices.Enum;
using MaximServices.Model;
using Microsoft.Extensions.Options;
using MySql.Data.MySqlClient;

namespace MaximServices.Repository
{
    public class MottoRepository
    {
        private readonly DataBaseRepository _dbrsp;

        public MottoRepository(DataBaseRepository dbrsp)
        {
            _dbrsp = dbrsp;
        }

        public void Dispose()
        {
            _dbrsp.Database.Dispose();
        }

        public Motto FindMotto(string id)
        {
            return _dbrsp.Database.Get<Motto>(id, null);
        }

        /// <summary>
        /// 找第一个未匹配词条的名言
        /// </summary>
        /// <returns></returns>
        public Motto FindOneUnMatchMotto()
        {
            //var sql = $" select * from motto t where status in ('10', '11') order by t.modify_time asc limit 1 ";

            var pgMain = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };

            var pga = new PredicateGroup { Operator = GroupOperator.Or, Predicates = new List<IPredicate>() };
            pga.Predicates.Add(Predicates.Field<Motto>(f => f.Status, Operator.Eq, MottoStatus.UnConfirm));
            pga.Predicates.Add(Predicates.Field<Motto>(f => f.Status, Operator.Eq, "11"));
            pgMain.Predicates.Add(pga);

            var sort = new List<ISort>
            {
                Predicates.Sort<Motto>(p => p.Modify_Time,true)
            };

            return _dbrsp.Database.GetList<Motto>(pgMain, sort, null, false).FirstOrDefault();
        }

        /// <summary>
        /// 最小词条数
        /// </summary>
        /// <param name="minMaximCount"></param>
        public int UnUsedEffectiveMaximCount()
        {
            var pgMain = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };

            pgMain.Predicates.Add(Predicates.Field<Motto>(f => f.Status, Operator.Eq, MottoStatus.Confirmed));
            pgMain.Predicates.Add(Predicates.Exists<ViewHistory>(
                    Predicates.Property<ViewHistory, Motto>(f => f.Motto_Id, Operator.Eq, t => t.Id)
                , true));

            return _dbrsp.Database.Count<Motto>(pgMain, null);
        }

        public List<Motto> GetList(string keyword, string status)
        {
            var pgMain = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };

            if (!string.IsNullOrWhiteSpace(keyword))
            {
                var pga = new PredicateGroup { Operator = GroupOperator.Or, Predicates = new List<IPredicate>() };

                pga.Predicates.Add(Predicates.Field<Motto>(f => f.Auth_Name, Operator.Like, $"%{keyword}%"));
                pga.Predicates.Add(Predicates.Field<Motto>(f => f.Content_Lite, Operator.Like, $"%{keyword}%"));
                pgMain.Predicates.Add(pga);
            }

            if (!string.IsNullOrWhiteSpace(status))
            {
                pgMain.Predicates.Add(Predicates.Field<Motto>(f => f.Status, Operator.Eq, status));
            }

            var sort = new List<ISort>
            {
                Predicates.Sort<Motto>(p => p.Modify_Time,true)
            };

            return _dbrsp.Database.GetList<Motto>(pgMain, sort, null, false).ToList();
        }

        public List<Motto> GetMottoByContentLite(List<string> lite)
        {
            var sql = $"select * from motto where content_lite in ({string.Join(',', lite)})";
            return _dbrsp.Database.Connection.Query<Motto>(sql).ToList();
        }

        public bool BatchCreate(List<Motto> list)
        {
            try
            {
                _dbrsp.Database.BeginTransaction();
                list.ForEach(d =>
                {
                    _dbrsp.Database.Insert(d, null);
                });
                _dbrsp.Database.Commit();
                return true;
            }
            catch (Exception)
            {
                _dbrsp.Database.Rollback();
                throw;
            }
        }

        public bool ReviewMotto(Motto model)
        {
            try
            {
                Motto query = _dbrsp.Database.Get<Motto>(model.Id, null);
                if (null == query)
                    throw new Exception("Id不存在");

                query.Status = model.Status;
                query.TagList = model.TagList;
                query.Baike_Url = model.Baike_Url;
                _dbrsp.Database.Update(query, null);
                return true;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        public List<string> GetTargetList()
        {
            try
            {
                string sql = $"SELECT DISTINCT taglist FROM maxim.motto  WHERE taglist is not null and taglist <> ''";
                List<string> result = _dbrsp.Database.Connection.Query<string>(sql).ToList();
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public List<Motto> GetListByRule(string keyWord, string auth, string target)
        {
            var pgMain = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
            if (string.IsNullOrWhiteSpace(target))
            {
                pgMain.Predicates.Add(Predicates.Field<Motto>(f => f.TagList, Operator.Eq, target));
            }
            if (string.IsNullOrWhiteSpace(auth))
            {
                pgMain.Predicates.Add(Predicates.Field<Motto>(f => f.Auth_Name, Operator.Eq, auth));
            }

            if (string.IsNullOrWhiteSpace(keyWord))
            {
                var pga = new PredicateGroup { Operator = GroupOperator.Or, Predicates = new List<IPredicate>() };

                pga.Predicates.Add(Predicates.Field<Motto>(f => f.Auth_Name, Operator.Like, $"%{keyWord}%"));
                pga.Predicates.Add(Predicates.Field<Motto>(f => f.Content_Lite, Operator.Like, $"%{keyWord}%"));
                pgMain.Predicates.Add(pga);
            }

            pgMain.Predicates.Add(Predicates.Field<Motto>(f => f.Status, Operator.Eq, MottoStatus.Confirmed));

            return _dbrsp.Database.GetList<Motto>(pgMain, null, null, false).ToList();
        }

        public List<Motto> GetAllList()
        {
            var p = Predicates.Field<Motto>(f => f.Status, Operator.Eq, MottoStatus.Confirmed);

            return _dbrsp.Database.GetList<Motto>(p, null, null, false).ToList();
        }

    }
}
